Realtime Analyzing in SentimentAgent

Rishabh Jain преди 12 години
родител
ревизия
4c8a9e3e5a
променени са 1 файла, в които са добавени 83 реда и са изтрити 0 реда
  1. 83 0
      app/models/agents/sentiment_agent.rb

+ 83 - 0
app/models/agents/sentiment_agent.rb

@@ -0,0 +1,83 @@
1
+require 'csv'
2
+
3
+module Agents
4
+    class SentimentAgent < Agent
5
+        class_attribute :anew
6
+
7
+        cannot_be_scheduled!
8
+
9
+        description <<-MD
10
+            The SentimentAgent generates `good-bad` (psychological valence or happiness index), `active-passive` (arousal),
11
+            and  `strong-weak` (dominance) score. It will output a value between 1 and 9.
12
+
13
+            Make sure the content this agent is analyzing have sufficient length to get respectable results.
14
+
15
+            Provide a JSONPath in `content` field where content is residing and set `expected_receive_period_in_days` to the maximum number of days you would allow to be passed between events being received by this agent.
16
+        MD
17
+
18
+        event_description <<-MD
19
+            Events look like:
20
+            {
21
+                :content   => "The quick brown fox jumps over the lazy dog.",
22
+                :valence   => 6.196666666666666,
23
+                :arousal   => 4.993333333333333,
24
+                :dominance => 5.63
25
+            }
26
+        MD
27
+
28
+        def default_options
29
+            {
30
+                :content => "$.message.text[*]",
31
+                :expected_receive_period_in_days => 1
32
+            }
33
+        end
34
+
35
+        def working?
36
+            last_receive_at && last_receive_at > options[:expected_receive_period_in_days].to_i.days.ago
37
+        end
38
+
39
+        def receive(incoming_events)
40
+            anew = self.class.sentiment_hash
41
+            incoming_events.each do |event|
42
+                Utils.values_at(event.payload, options[:content]).each do |content|
43
+                    sent_values = sentiment_values anew, content
44
+                    create_event :payload => {:content => content, 
45
+                                              :valence => sent_values[0], 
46
+                                              :arousal => sent_values[1], 
47
+                                              :dominance => sent_values[2]}
48
+                end
49
+            end
50
+        end
51
+
52
+        def validate_options
53
+            errors.add(:base, "content and expected_receive_period_in_days must be present") unless options[:content].present? && options[:expected_receive_period_in_days].present?
54
+        end
55
+
56
+        def self.sentiment_hash
57
+            unless self.anew
58
+                self.anew = {}
59
+                CSV.foreach Rails.root.join('data/anew.csv') do |row|
60
+                    self.anew[row[0]] = row.values_at(2,4,6).map {|val| val.to_f}
61
+                end
62
+            end
63
+            self.anew  
64
+        end
65
+
66
+        def sentiment_values(anew,text)
67
+            valence, arousal, dominance, freq = [0] * 4
68
+            text.downcase.strip.gsub(/[^a-z ]/,"").split.each do |word|
69
+                if anew.has_key? word
70
+                    valence   += anew[word][0]
71
+                    arousal   += anew[word][1]
72
+                    dominance += anew[word][2]
73
+                    freq      += 1
74
+                end
75
+            end
76
+            if valence != 0
77
+                [valence/freq, arousal/freq, dominance/freq]
78
+            else
79
+                ["Insufficient data for meaningful answer"] * 3
80
+            end
81
+        end
82
+    end
83
+end